home *** CD-ROM | disk | FTP | other *** search
- /*
- Amiga port by Oliver Gantert
-
- 27.04.2000 - fixed some compiler warnings
- 22.06.2000 - DrawMissile0/1/3() optimized (double to float)
- */
- /*
-
- ORBIT, a freeware space combat simulator
- Copyright (C) 1999 Steve Belczyk <steve1@genesis.nred.ma.us>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- */
-
- #include "orbit.h"
-
- void InitMissiles()
- /*
- * Set up missile structures
- */
- {
- int i;
-
- /* Mark all missiles as unused */
- for (i=0; i<NMSLS; i++)
- {
- msl[i].age = 0.0;
- }
- }
-
- int FindMissile()
- /*
- * Find unused missile
- */
- {
- int i, oldest;
- double maxage;
-
- /* Look for free missile, or oldest */
- for (i=0; i<NMSLS; i++)
- {
- if (msl[i].age == 0.0) return (i);
-
- if (i == 0)
- {
- maxage = msl[i].age;
- oldest = i;
- }
- else
- {
- if (msl[i].age > maxage)
- {
- maxage = msl[i].age;
- oldest = i;
- }
- }
- }
-
- /* None free, return oldest */
- return (oldest);
- }
-
- void FireMissile (double *pos, double *vel, double *dir, int friendly, int wep, int owner)
- /*
- * Fire missile at the given location and velocity, in
- * the specified direction
- */
- {
- int m;
- double v[3];
-
- /* Find a free missile */
- m = FindMissile();
-
- /* Set it up */
- msl[m].age = deltaT;
- Vset (msl[m].pos, pos);
-
- if (friendly && !am_client && !am_server)
- {
- Vmul (v, player.up, -0.005);
- Vadd (msl[m].pos, msl[m].pos, v);
- }
-
- Vmul (msl[m].vel, dir, weapon[wep].speed);
- Vadd (msl[m].vel, msl[m].vel, vel);
-
- msl[m].friendly = friendly;
- msl[m].weapon = wep;
- msl[m].owner = owner;
-
- /* Play the sound */
- /* if (sound) PlaySound ("phaser.wav", NULL, SND_ASYNC | SND_FILENAME); */
- if (sound) PlayAudio (SOUND_FIRE);
- }
-
- void MoveMissiles()
- /*
- * Move all the missiles
- */
- {
- int m, t, p;
- double v[3], deltav[3];
-
- /* Loop through missiles */
- for (m=0; m<NMSLS; m++)
- {
- /* If missile in use */
- if (msl[m].age > 0.0)
- {
- /* Bump age */
- msl[m].age += deltaT;
-
- /* See if expired */
- if (msl[m].age > weapon[msl[m].weapon].expire)
- {
- DestroyMissile (m);
- return;
- }
-
- /* See if missile has hit planet */
- if ((-1) != (p = InsidePlanet (msl[m].pos)))
- {
- /* Missile has hit planet */
-
- /* Move point of impact just above planet surface */
- Vsub (v, msl[m].pos, planet[p].pos);
- Normalize (v);
- Vmul (v, v, planet[p].radius*1.05);
- Vadd (v, v, planet[p].pos);
- Boom (v, weapon[msl[m].weapon].yield/100.0);
- DestroyMissile (m);
- return;
- }
-
- /* See if missile hit a target */
- if ((-1) != (t = HitTarget (m)))
- {
- /* Missle hit target */
- MissileHitTarget (m, t);
- return;
- }
-
- /* See if missile hit player */
- if (!msl[m].friendly && !am_client &&
- (state != STATE_DEAD1) && (state != STATE_DEAD2) )
- {
- if (TARGDIST2 > Dist2 (msl[m].pos[0], msl[m].pos[1], msl[m].pos[2],
- player.pos[0], player.pos[1], player.pos[2]))
- {
- /* Missile hit player */
- MissileHitPlayer (m);
- return;
- }
- }
-
- /* Else update its position */
- if (gravity)
- {
- Gravity (deltav, msl[m].pos);
- Vadd (msl[m].vel, msl[m].vel, deltav);
- }
- Vmul (v, msl[m].vel, deltaT);
- Vadd (msl[m].pos, msl[m].pos, v);
- }
- }
- }
-
- void DestroyMissile (int m)
- /*
- * Missile has expired
- */
- {
- msl[m].age = 0.0;
- }
-
- void DrawMissiles ()
- /*
- * Draw all the missiles
- */
- {
- int m;
-
- for (m=0; m<NMSLS; m++)
- {
- if (msl[m].age > 0.0) DrawMissile (m);
- }
- }
-
- void DrawMissile (int m)
- /*
- * Draw this missile
- */
- {
- glPushMatrix();
- glDisable (GL_LIGHTING);
- glDisable (GL_CULL_FACE);
-
- switch (weapon[msl[m].weapon].renderer)
- {
- case 0: DrawMissile0 (m);
- break;
-
- case 1: DrawMissile1 (m);
- break;
-
- case 2: DrawMissile2 (m);
- break;
-
- case 3: DrawMissile3 (m);
- break;
-
- case 4: DrawMissile4 (m);
- break;
- }
-
- glEnable (GL_CULL_FACE);
- glEnable (GL_LIGHTING);
- glPopMatrix();
- }
-
- void DrawMissile0 (int m)
- {
- float r;
- double v[3];
-
- /* Figure how much to spin missile */
- r = (float)absT - ((float)(int)absT);
- r *= 360.0;
-
- glColor3fv (weapon[msl[m].weapon].color);
-
- Vsub (v, msl[m].pos, player.pos);
- glTranslated (v[0], v[1], v[2]);
- glRotatef (r, 0.3, 1.0, 0.6);
-
- glBegin (GL_LINES);
- glVertex3f (-0.01, 0.0, 0.0);
- glVertex3f ( 0.01, 0.0, 0.0);
- glVertex3f (0.0, -0.01, 0.0);
- glVertex3f (0.0, 0.01, 0.0);
- glVertex3f (0.0, 0.0, -0.01);
- glVertex3f (0.0, 0.0, 0.01);
- glEnd();
- }
-
- void DrawMissile1 (int m)
- {
- float r;
- double v[3];
-
- /* Figure how much to spin missile */
- r = (float)absT - ((float)(int)absT);
- r *= 360.0;
-
- glColor3fv (weapon[msl[m].weapon].color);
-
- Vsub (v, msl[m].pos, player.pos);
- glTranslated (v[0], v[1], v[2]);
- glRotatef (r, 0.3, 1.0, 0.6);
-
- glBegin (GL_LINES);
- glVertex3f (-0.01, 0.0, 0.0);
- glVertex3f ( 0.01, 0.0, 0.0);
- glVertex3f (0.0, -0.01, 0.0);
- glVertex3f (0.0, 0.01, 0.0);
- glVertex3f (0.0, 0.0, -0.01);
- glVertex3f (0.0, 0.0, 0.01);
- glEnd();
- }
-
- void DrawMissile2 (int m)
- {
- double v1[3], v2[3], v3[3], v4[4], vel[3], v[3];
-
- glColor3fv (weapon[msl[m].weapon].color);
-
- Vsub (v, msl[m].pos, player.pos);
- glTranslated (v[0], v[1], v[2]);
-
- Vmul (vel, msl[m].vel, 0.1);
-
- glBegin (GL_QUADS);
-
- v1[0] = 0.01; v1[1] = 0.0; v1[2] = 0.0;
- v2[0] = -0.01; v2[1] = 0.0; v2[2] = 0.0;
- Vsub (v3, v2, vel);
- Vsub (v4, v1, vel);
- glVertex3dv (v1);
- glVertex3dv (v2);
- glVertex3dv (v3);
- glVertex3dv (v4);
-
- v1[0] = 0.0; v1[1] = 0.01; v1[2] = 0.0;
- v2[0] = 0.0; v2[1] = -0.01; v2[2] = 0.0;
- Vsub (v3, v2, vel);
- Vsub (v4, v1, vel);
- glVertex3dv (v1);
- glVertex3dv (v2);
- glVertex3dv (v3);
- glVertex3dv (v4);
-
- v1[0] = 0.0; v1[1] = 0.0; v1[2] = 0.01;
- v2[0] = 0.0; v2[1] = 0.0; v2[2] = -0.01;
- Vsub (v3, v2, vel);
- Vsub (v4, v1, vel);
- glVertex3dv (v1);
- glVertex3dv (v2);
- glVertex3dv (v3);
- glVertex3dv (v4);
-
- glEnd();
- }
-
- void DrawMissile3 (int m)
- {
- float r;
- double v[3];
-
- /* Figure how much to spin missile */
- r = (float)absT - ((float)(int)absT);
- r *= 360.0;
-
- glColor3fv (weapon[msl[m].weapon].color);
-
- Vsub (v, msl[m].pos, player.pos);
- glTranslated (v[0], v[1], v[2]);
- glRotatef (r, 0.3, 1.0, 0.6);
- glScalef (0.01, 0.01, 0.01);
-
- glutSolidTetrahedron ();
- }
-
- void DrawMissile4 (int m)
- {
- int i;
- double v[3], u[3];
-
- glColor3fv (weapon[msl[m].weapon].color);
-
- Vsub (u, msl[m].pos, player.pos);
- glTranslated (u[0], u[1], u[2]);
-
- glBegin (GL_LINE_LOOP);
- for (i=0; i<6; i++)
- {
- v[0] = rnd(0.04) - 0.01;
- v[1] = rnd(0.04) - 0.01;
- v[2] = rnd(0.04) - 0.01;
- glVertex3dv (v);
- }
- glEnd();
- }
-
- void MissileHitPlayer (int m)
- /*
- * Missile m hit player. Ouch!
- */
- {
- /* Flash screen red */
- palette_flash = 2;
-
- /* Damage shields */
- player.shields -= weapon[msl[m].weapon].yield;
-
- /* Get rid of missile */
- DestroyMissile (m);
-
- /* See if player died */
- if (vulnerable && (player.shields < 0.0) && !am_client)
- {
- if (am_server)
- {
- /* Tell other clients */
- NetDestroyClient (server.client, FindClientByTarget (msl[m].owner));
- NetPlayerDies();
- }
- else
- {
- /* Single player games, reset */
- InitPlayer();
- ReadMission (mission.fn);
- Mprint ("You were killed! Restarting mission.");
- }
- }
-
- if (player.shields < 0.0) player.shields = 100.0;
- }
-
- void MissileHitTarget (int m, int t)
- /*
- * Missile m hit target t. Go get 'em!
- */
- {
- int e;
-
- Boom (msl[m].pos, weapon[msl[m].weapon].yield/100.0);
-
- target[t].shields -= weapon[msl[m].weapon].yield;
- if (target[t].shields < 0.0) target[t].shields = 0.0;
-
- /* Announce to network */
- if (am_server) NetHitTarget (t, m);
-
- /* See if we set off an event */
- for (e=0; e<NEVENTS; e++)
- {
- if (event[e].pending &&
- event[e].enabled &&
- (event[e].trigger == EVENT_SHIELDS) &&
- (!strcasecmp (event[e].cvalue, target[t].name)) &&
- (target[t].shields <= event[e].fvalue) )
- {
- EventAction (e);
- }
- }
-
- /* See if target is destroyed */
- if (!am_client && target[t].shields <= 0.0)
- {
- /* Announce to network */
- NetDestroyTarget (t, m);
-
- /* Kablooie! */
- Boom (target[t].pos, 1.0);
- if (!am_server) DestroyTarget (t);
- if (am_server) target[t].shields = 100.0;
- }
- DestroyMissile (m);
- }
-